if (!global.ShadowMamba) {
global.ShadowMamba = {};
        }
var sm = global.ShadowMamba;

function sm_override(o) {
    // this function is responsible for dealing all damage and healing for any skill, item, or effect
var effecter = o.effecter;
var skill = o.skill;
var item = o.item;
var effect = o.effect;
var unit = o.cur_unit;
var target = o.target_unit;
var tile = o.target_tile;
var flags = effecter.ScriptFlags;
// return { handled: true }; // handled indicates this script decided to handle it and the engine should not do any further perform skill logic. // You can put the name of a function after handled to specify what is done, neat.
}

function sm_before_damage(b) {
var source = b.source_unit;
var target = b.target_unit;
var targetTile = b.target_tile;
var effecter = b.effecter;
var skill = b.skill;
var item = b.item;
var effect = b.effect;
var point = b.point; // the point (as a point object) effected
var amount = b.amount;
//var flags = effecter.ScriptFlags;
return { handled: false }; // handled indicates this script decided to handle it and the engine should not do any further point damaging logic
}

function sm_after_damage(d) {
var source = d.source_unit;
var target = d.target_unit;
var effecter = d.effecter;
var point = d.point;
var amount = d.amount;
if (!effecter) return;
var eFlags = effecter.ScriptFlags;
if (!source) return
var sFlags = source.ScriptFlags;
var sourceItems = source.GetEquippedItems();
var flags = target.ScriptFlags;
var targetItems = target.GetEquippedItems();
if (flags.get("after_damage_sound")) {
var DSound = flags.get("after_damage_sound");
DSound = DSound.split(",");
for (var count = 0; count < DSound.length; count++) {
var split2 = DSound[count].split(":");
var DPoints = split2[0].split("|");
for (var i = 0; i < DPoints.length; i++) {
if (point.LookupName == DPoints[i]) {
if (split2[1]) {
var sound = split2[1];
randomSound(chooseFromARandomSelectString(sound));
}
}
}
}
}
if (flags.get("source_effects_after_damage")) {
if (eFlags.get("cannot_be_countered") || sFlags.get("cannot_be_countered")) {
return;
}
if (sourceItems && sourceItems.length > 0) {
for (var i = 0; i < sourceItems.length; i++) {
var item = sourceItems[i];
if (item.ScriptFlags.get("cannot_be_countered")) {
return;
}
}
}
if (source.Effects && source.Effects.length > 0) {
for (var i = 0; i < source.Effects.length; i++) {
var effect = source.Effects[i];
if (effect.ScriptFlags.get("cannot_be_countered")) {
return;
}
}
}
var effects = flags.get("source_effects_after_damage");
effects = effects.split("; ");
for (var count = 0; count < effects.length; count++) {
var split2 = effects[count].split(":")
var DPoints = split2[0].split("|");
for (var i = 0; i < DPoints.length; i++) {
if (point.LookupName == DPoints[i]) {
if (split2[1]) {
var hasPercent = false;
if (split2[2]) hasPercent = true;
var work = true;
if (hasPercent) {
chance = parseInt(split2[2]);
if (chance<=0||chance>100) chance = 100;
if (shared.Calculate("1r100")>chance) work = false;
}
var range = false;
if (split2[3]) range = true;
if (range) {
var distance = shared.Map.GetDistance(source.Tile.X, source.Tile.Y, target.Tile.X, target.Tile.Y);
if (distance <= split2[3]) range = true;
if (distance > split2[3]) work = false;
}
if (work) {
var newEffects = chooseFromARandomSelectString(split2[1]).split(",");
for (var b = 0; b < newEffects.length; b++) {
if (source)
shared.ApplyEffect(newEffects[b], source, source.Tile);
}
}
}
}
}
}
}
if (targetItems && targetItems.length > 0) {
for (var p = 0; p < targetItems.length; p++) {
var iFlags = targetItems[p].ScriptFlags;
if (iFlags.get("source_effects_after_damage")) {
if (eFlags.get("cannot_be_countered") || sFlags.get("cannot_be_countered")) {
return;
}
if (sourceItems && sourceItems.length > 0) {
for (var i = 0; i < sourceItems.length; i++) {
var item = sourceItems[i];
if (item.ScriptFlags.get("cannot_be_countered")) {
return;
}
}
}
if (source.Effects && source.Effects.length > 0) {
for (var i = 0; i < source.Effects.length; i++) {
var effect = source.Effects[i];
if (effect.ScriptFlags.get("cannot_be_countered")) {
return;
}
}
}
var effects = iFlags.get("source_effects_after_damage");
effects = effects.split("; ");
for (var count = 0; count < effects.length; count++) {
var split2 = effects[count].split(":")
var DPoints = split2[0].split("|");
for (var i = 0; i < DPoints.length; i++) {
if (point.LookupName == DPoints[i]) {
if (split2[1]) {
var hasPercent = false;
if (split2[2]) hasPercent = true;
var work = true;
if (hasPercent) {
chance = parseInt(split2[2]);
if (chance<=0||chance>100) chance = 100;
if (shared.Calculate("1r100")>chance) work = false;
}
var range = false;
if (split2[3]) range = true;
if (range) {
var distance = shared.Map.GetDistance(source.Tile.X, source.Tile.Y, target.Tile.X, target.Tile.Y);
if (distance <= split2[3]) range = true;
if (distance > split2[3]) work = false;
}
if (work) {
var newEffects = chooseFromARandomSelectString(split2[1]).split(",");
for (var b = 0; b < newEffects.length; b++) {
if (source)
shared.ApplyEffect(newEffects[b], source, source.Tile);
}
}
}
}
}
}
}
}
}
if (target.Effects && target.Effects.length > 0) {
for (var p = 0; p < target.Effects.length; p++) {
var fxFlags = target.Effects[p].ScriptFlags;
if (fxFlags.get("source_effects_after_damage")) {
if (eFlags.get("cannot_be_countered") || sFlags.get("cannot_be_countered")) {
return;
}
if (sourceItems && sourceItems.length > 0) {
for (var i = 0; i < sourceItems.length; i++) {
var item = sourceItems[i];
if (item.ScriptFlags.get("cannot_be_countered")) {
return;
}
}
}
if (source.Effects && source.Effects.length > 0) {
for (var i = 0; i < source.Effects.length; i++) {
var effect = source.Effects[i];
if (effect.ScriptFlags.get("cannot_be_countered")) {
return;
}
}
}
var effects = fxFlags.get("source_effects_after_damage");
effects = effects.split("; ");
for (var count = 0; count < effects.length; count++) {
var split2 = effects[count].split(":")
var DPoints = split2[0].split("|");
for (var i = 0; i < DPoints.length; i++) {
if (point.LookupName == DPoints[i]) {
if (split2[1]) {
var hasPercent = false;
if (split2[2]) hasPercent = true;
var work = true;
if (hasPercent) {
chance = parseInt(split2[2]);
if (chance<=0||chance>100) chance = 100;
if (shared.Calculate("1r100")>chance) work = false;
}
var range = false;
if (split2[3]) range = true;
if (range) {
var distance = shared.Map.GetDistance(source.Tile.X, source.Tile.Y, target.Tile.X, target.Tile.Y);
if (distance <= split2[3]) range = true;
if (distance > split2[3]) work = false;
}
if (work) {
var newEffects = chooseFromARandomSelectString(split2[1]).split(",");
for (var b = 0; b < newEffects.length; b++) {
if (source)
shared.ApplyEffect(newEffects[b], source, source.Tile);
}
}
}
}
}
}
}
}
}
if (target.PassiveSkills && target.PassiveSkills.length > 0) {
for (var p = 0; p < target.PassiveSkills.length; p++) {
var psFlags = target.PassiveSkills[p].ScriptFlags;
if (psFlags.get("source_effects_after_damage")) {
if (eFlags.get("cannot_be_countered") || sFlags.get("cannot_be_countered")) {
return;
}
if (sourceItems && sourceItems.length > 0) {
for (var i = 0; i < sourceItems.length; i++) {
var item = sourceItems[i];
if (item.ScriptFlags.get("cannot_be_countered")) {
return;
}
}
}
if (source.Effects && source.Effects.length > 0) {
for (var i = 0; i < source.Effects.length; i++) {
var effect = source.Effects[i];
if (effect.ScriptFlags.get("cannot_be_countered")) {
return;
}
}
}
var effects = psFlags.get("source_effects_after_damage");
effects = effects.split("; ");
for (var count = 0; count < effects.length; count++) {
var split2 = effects[count].split(":")
var DPoints = split2[0].split("|");
for (var i = 0; i < DPoints.length; i++) {
if (point.LookupName == DPoints[i]) {
if (split2[1]) {
var hasPercent = false;
if (split2[2]) hasPercent = true;
var work = true;
if (hasPercent) {
chance = parseInt(split2[2]);
if (chance<=0||chance>100) chance = 100;
if (shared.Calculate("1r100")>chance) work = false;
}
var range = false;
if (split2[3]) range = true;
if (range) {
var distance = shared.Map.GetDistance(source.Tile.X, source.Tile.Y, target.Tile.X, target.Tile.Y);
if (distance <= split2[3]) range = true;
if (distance > split2[3]) work = false;
}
if (work) {
var newEffects = chooseFromARandomSelectString(split2[1]).split(",");
for (var b = 0; b < newEffects.length; b++) {
if (source)
shared.ApplyEffect(newEffects[b], source, source.Tile);
}
}
}
}
}
}
}
}
}
if (flags.get("target_effects_after_damage")) {
var effects = flags.get("target_effects_after_damage");
effects = effects.split("; ");
for (var count = 0; count < effects.length; count++) {
var split2 = effects[count].split(":")
var DPoints = split2[0].split("|");
for (var i = 0; i < DPoints.length; i++) {
if (point.LookupName == DPoints[i]) {
if (split2[1]) {
var hasPercent = false;
if (split2[2]) hasPercent = true;
var work = true;
if (hasPercent) {
chance = parseInt(split2[2]);
if (chance<=0||chance>100) chance = 100;
if (shared.Calculate("1r100")>chance) work = false;
}
if (work) {
var newEffects = chooseFromARandomSelectString(split2[1]).split(",");
for (var b = 0; b < newEffects.length; b++) {
shared.ApplyEffect(newEffects[b], target, target.Tile);
}
}
}
}
}
}
}
// Now for counter-attacking, oh my!
if (target.PassiveSkills && target.PassiveSkills.length > 0) {
for (var i = 0; i < target.PassiveSkills.length; i++) {
var psFlags = target.PassiveSkills[i].ScriptFlags;
if (psFlags.get("counter_attack")) {
if (!source || source.Dead || target.Dead)
return false;
if (counterImmune(source, target, effecter))
return false;
if (psFlags.get("counter_attack_cost")) {
var caCost = psFlags.get("counter_attack_cost");
caCost = caCost.split(",");
for (var count = 0; count < caCost.length; count++) {
var split2 = caCost[count].split(":");
if (target.Points.get(split2[0])) {
var CPoint = target.Points.get(split2[0]);
if (!split2[1]) {
say("Error: If using the counter attack cost flag you must specify a cost!");
}
if (split2[1]) {
if (CPoint.Current < split2[1]) return;
if (CPoint.Current >= split2[1]) {
var subtract = split2[1];
CPoint.Current = (CPoint.Current - subtract);
shared.ShareUnitPointUpdate(target, [split2[0]]);
}
}
}
}
}
var counterAttack = psFlags.get("counter_attack");
var counterAttackChance;
if (psFlags.get("counter_attack_chance"))
counterAttackChance = psFlags.get("counter_attack_chance");
else if (!psFlags.get("counter_attack_chance"))
counterAttackChance = flags.get("counter_attack_chance");
var counterAttackRange = psFlags.get("counter_attack_range");
var random = counterAttack.split(",");
for (var i = 0; i < random.length; i++) {
random[i] = random[i].split(":");
}
if (!counterAttackChance) {
say("Error: You must supply a counter attack chance!");
return;
}
if (!counterAttackRange) {
say("Error: You must supply a maximum range at which counter attacking can occur!");
return;
}
var hasPercent = false;
if (counterAttackChance) hasPercent = true;
var work = true;
if (hasPercent) {
var chance = determineModifier(target, counterAttackChance, "counter_attack_chance_mod")
var math = Math.random().toFixed(2);
if (math <= chance) {
work = true;
}
else if (math > chance) {
work = false;
}
}
var range = false;
if (counterAttackRange) range = true;
if (range) {
var distance = shared.Map.GetDistance(source.Tile.X, source.Tile.Y, target.Tile.X, target.Tile.Y);
if (distance <= counterAttackRange) range = true;
if (distance > counterAttackRange) work = false;
}
if (work) {
if (flags.get("counter_attack_damage_points")) {
var pointToCounter = flags.get("counter_attack_damage_points");
pointToCounter = pointToCounter.split(",");
for (var c = 0; c < pointToCounter.length; c++) {
if (point.LookupName != pointToCounter[c]) return;
if (pointToCounter[c].Current == 0) return;
}
}
say("Counter attack!");
if (psFlags.get("counter_attack_sound")) {
randomSound(chooseFromARandomSelectString(psFlags.get("counter_attack_sound")));
}
if (psFlags.get("counter_attack_message")) {
var msg = chooseFromARandomSelectString(psFlags.get("counter_attack_message"));
say((msg).format(target.GetName(),source.GetName()));
}
for (var counter = 0; counter < random.length; counter++) {
//say(target.GetName() +" is definitely a bitch!");
target.DoDamageTo(source, random[counter][1], random[counter][0], random[counter][2]);
return;
}
}
}
}
}
if (flags.get("counter_attack")) {
if (!source || source.Dead || target.Dead)
return false;
if (counterImmune(source, target, effecter))
return false;
if (flags.get("counter_attack_cost")) {
var caCost = flags.get("counter_attack_cost");
caCost = caCost.split(",");
for (var count = 0; count < caCost.length; count++) {
var split2 = caCost[count].split(":");
if (target.Points.get(split2[0])) {
var CPoint = target.Points.get(split2[0]);
if (!split2[1]) {
say("Error: If using the counter attack cost flag you must specify a cost!");
}
if (split2[1]) {
split2[1] = determineModifier(target, split2[1], "counter_attack_cost_mod");
if (CPoint.Current < split2[1]) return;
if (CPoint.Current >= split2[1]) {
var subtract = split2[1];
CPoint.Current = (CPoint.Current - subtract);
shared.ShareUnitPointUpdate(target, [split2[0]]);
}
}
}
}
}
var counterAttack = flags.get("counter_attack");
var counterAttackChance = flags.get("counter_attack_chance");
var counterAttackRange = flags.get("counter_attack_range");
var random = counterAttack.split(",");
for (var i = 0; i < random.length; i++) {
random[i] = random[i].split(":");
}
if (!counterAttackChance) {
say("Error: You must supply a counter attack chance!");
return;
}
if (!counterAttackRange) {
say("Error: You must supply a maximum range at which counter attacking can occur!");
return;
}
var hasPercent = false;
if (counterAttackChance) hasPercent = true;
var work = true;
if (hasPercent) {
//POKAGE. Input here.
var math = Math.random().toFixed(2);
var chance = determineModifier(target, counterAttackChance, "counter_attack_chance_mod")
if (math <= chance) {
work = true;
}
else if (math > chance) {
work = false;
}
}
var range = false;
if (counterAttackRange) range = true;
if (range) {
var distance = shared.Map.GetDistance(source.Tile.X, source.Tile.Y, target.Tile.X, target.Tile.Y);
if (distance <= counterAttackRange) range = true;
if (distance > counterAttackRange) work = false;
}
if (work) {
if (flags.get("counter_attack_damage_points")) {
var pointToCounter = flags.get("counter_attack_damage_points");
pointToCounter = pointToCounter.split(",");
for (var c = 0; c < pointToCounter.length; c++) {
if (point.LookupName != pointToCounter[c]) return;
if (pointToCounter[c].Current == 0) return;
}
}
say("Counter attack!");
if (flags.get("counter_attack_sound")) {
randomSound(chooseFromARandomSelectString(flags.get("counter_attack_sound")));
}
if (flags.get("counter_attack_message")) {
var msg = chooseFromARandomSelectString(flags.get("counter_attack_message"));
say((msg).format(target.GetName(),source.GetName()));
}
for (var counter = 0; counter < random.length; counter++) {
//say(target.GetName() +" is definitely a bitch!");
target.DoDamageTo(source, random[counter][1], random[counter][0], random[counter][2]);
return;
}
}
}
//End of the super-long counter-attacking bit.
// Effects on amount thinggy

if (flags.get("effects_on_amount")) {
var newEffects = flags.get("effects_on_amount");
newEffects = newEffects.split(";");
for (var count = 0; count < newEffects.length; count++) {
var split2 = newEffects[count].split(":");
if (target.Points.get(split2[0])) {
var CPoint = target.Points.get(split2[0]);
if (!split2[1] || !split2[2] || !split2[3]) {
say("Error!");
return;
}
if (split2[1]) {
say(split2[1]+" And stuff.");
if (split2[1] == ">=") {
if (split2[2]) {
if (CPoint.Current <parseInt( split2[2])) {
if (split2[3]) {
var effects = split2[3].split(",");
for (var i = 0; i < effects.length; i++) {
shared.RemoveEffect(effects[i], target, null);
}
}
}
if (CPoint.Current >= parseInt(split2[2])) {
if (split2[3]) {
var effects = split2[3].split(",");
for (var i = 0; i < effects.length; i++) {
shared.ApplyEffect(effects[i], target, null);
}
}
}
}
}
if (split2[1] == "<=") {
if (split2[2]) {
if (CPoint.Current > parseInt(split2[2])) {
if (split2[3]) {
var effects = split2[3].split(",");
for (var i = 0; i < effects.length; i++) {
shared.RemoveEffect(effects[i], target, null);
}
}
}
if (CPoint.Current <= parseInt(split2[2])) {
say("One thing, bitch.");
if (split2[3]) {
var effects = split2[3].split(",");
for (var i = 0; i < effects.length; i++) {
shared.ApplyEffect(effects[i], target, null);
}
}
}
}
}

}
}
}
}


}


function sm_randomDamage(r) {
var source = r.source_unit;
var target = r.target_unit;
var tile = r.target_tile;
var skill = r.skill;
var item = r.item;
var effecter;
if (skill)
effecter = skill;
else if (item)
effecter = item;
var flags = effecter.ScriptFlags;
if (flags.get("random_damage")) {
var randomDamage = slashString(flags.get("random_damage"));
var random = randomDamage.split(",");
for (var i = 0; i < random.length; i++) {
random[i] = random[i].split(":");
}
for (var counter = 0; counter < random.length; counter++) {
//say(target.GetName() +" is a bitch!");
if (random[counter][2]) {
var type = chooseFromARandomSelectString(random[counter][2]);
}
source.DoDamageTo(target, random[counter][1], random[counter][0], type);
}
/*
if (effecter.AllFlags.get("tile")) {
if (tile.Units.length >= 1) {
for(var uCounter = 0; uCounter < tile.Units.length; uCounter++) {
for (var counter = 0; counter < random.length; counter++) {
say(tile.Units[uCounter].GetName());
source.DoDamageTo(tile.Units[uCounter], random[counter][1], random[counter][0], random[counter][2]);
}
}
}
if (tile.Structures.length >= 1) {
for(var sCounter = 0; sCounter < tile.Structures.length; sCounter++) {
for (var counter = 0; counter < random.length; counter++) {
source.DoDamageTo(tile.Structures[sCounter], random[counter][1], random[counter][0], random[counter][2]);
}
}
}
}
*/
}
}



function sm_drainPoint(d) {
var source = d.source_unit;
var target = d.target_unit;
var tile = d.target_tile;
var amount = d.amount;
var skill = d.skill;
var item = d.item;
var effecter;
if (skill)
effecter = skill;
else if (item)
effecter = item;
var flags = effecter.ScriptFlags;
if (flags.get("drain_point")) {
var drainPoint = flags.get("drain_point");
var drain = drainPoint.split(",");
for (var i = 0; i < drain.length; i++) {
drain[i] = drain[i].split(":");
}
for (var counter = 0; counter < drain.length; counter++) {
if (target.Points.get(drain[counter][0])) {
var amount = chooseFromARandomSelectString(drain[counter][1]);
/*
var SPoints = source.Points.get(drain[counter][0]);
var TPoints = target.Points.get(drain[counter][0]);
// For when the target's current point is less than the amount being drained.
if ((SPoints.LookupName == TPoints.LookupName)) {
if (TPoints.Current < amount) {
say(target.GetName()+ " loses "+TPoints.Current + " " + drain[counter][0]);
{
target.DoRestoreTo(source, TPoints.Current, drain[counter][0]);
}
var subtract = TPoints.Current;
TPoints.Current = (TPoints.Current - subtract);
shared.ShareUnitPointUpdate(target, [drain[counter][0]]);
}
if ((TPoints.Current > amount) || (TPoints.Current == amount)) {*/
source.DoDamageTo(target, amount, drain[counter][0], drain[counter][2]);
target.DoRestoreTo(source, amount, drain[counter][0]);
//}
}
}
}
}

/*
function sm_absorbDamage(a) {
var source = a.source_unit;
var target = a.target_unit;
var tile = a.target_tile;
var point = a.point;
var amount = a.amount;
var skill = a.skill;
var item = a.item;
var effect = a.effect;
var effecter;
if (skill)
effecter = skill;
if (item)
effecter = item;
else if (effect)
effecter = effect;
if (target.ScriptFlags.get("absorb_damage")) {
var absorbDamage = target.ScriptFlags.get("absorb_damage");
absorbDamage = absorbDamage.split(",");
for (var i = 0; i < absorbDamage.length; i++) {
absorbDamage[i] = absorbDamage[i].split(":");
}
for (var counter = 0; counter < absorbDamage.length; counter++) {
if (target.Points.get(absorbDamage[counter][0])) {
say(target.GetName()+" absorbs the damage from "+source.GetName()+"'s attack!")
source.DoRestoreTo(target, amount, absorbDamage[counter][0]);
}
}
}
}
*/
